﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aij1.Model;
using System.IO;
using System.Web;
using Aij1.Utils;
using DevExpress.Xpo;
using DevExpress.Web.ASPxClasses.Internal;
using System.Web.Caching;
using System.Data;
using System.Drawing;
using DevExpress.Data.Filtering;
using System.Drawing.Imaging;

namespace Aij1.BLL
{
    /// <summary>
    /// 相册业务类
    /// </summary>
    public class AlbumData
    {
        public static int SnapWidth = 120;
        public static int SnapHeight = 120;

        public static A_Photo CreatePhoto(Session session, Image sourceImg, string title)
        {
            string resultFileName = Config.GetUniqueName();
            string albumUrl = Config.UploadDir;

            string resultFileUrl = albumUrl + resultFileName + '.' + GetFormat(sourceImg.RawFormat);
            string snapShotUrl = Config.GetAlbumSnapShotUrl(albumUrl) + resultFileName + "_s." + GetFormat(sourceImg.RawFormat);

            Image snapImage = WebHelper.CreateSnapShot(sourceImg, AlbumData.SnapWidth, AlbumData.SnapHeight);

            A_Photo photo = new A_Photo(session)
            {
                Title = title,
                ImageType = GetFormat(sourceImg.RawFormat),
                Url = resultFileUrl,
                SnapShotUrl = snapShotUrl,
                EditTime = DateTime.Now,
                Width = sourceImg.Width,
                Height = sourceImg.Height,
                SnapShotWidth = snapImage.Width,
                SnapShotHeight = snapImage.Height,
            };
            sourceImg.Save(HttpContext.Current.Server.MapPath(resultFileUrl), sourceImg.RawFormat);
            snapImage.Save(HttpContext.Current.Server.MapPath(snapShotUrl), sourceImg.RawFormat);
            return photo;
        }

        static Image GetImageFromUrl(string url)
        {
            if (!url.StartsWith("http://"))
            {
                return Image.FromFile(HttpContext.Current.Server.MapPath(url));
            }
            else
            {
                return WebHelper.GetImageFromUrl(url);
            }
        }

        public static A_Photo ReCalcPhoto(A_Photo photo)
        {
            Image img = GetImageFromUrl(photo.Url);
            if (img == null) return photo;
            Image snapImage = null;
            if (img != null)
            {
                photo.Width = img.Width;
                photo.Height = img.Height;
                photo.ImageType = GetFormat(img.RawFormat);
            }

            if (!String.IsNullOrEmpty(photo.SnapShotUrl) && photo.SnapShotUrl != photo.Url)
            {
                snapImage = GetImageFromUrl(photo.SnapShotUrl);
            }
            else
            {
                photo.SnapShotUrl = photo.Url;
                snapImage = img;
            }

            if (snapImage == null) return photo;

            int snapWidth = snapImage.Width;
            int snapHeight = snapImage.Height;

            if (snapWidth / SnapWidth >= 2 || snapHeight / SnapHeight >= 2 || photo.SnapShotUrl == photo.Url)
            {
                if (((decimal)snapImage.Width) / snapImage.Height <= ((decimal)SnapWidth) / SnapHeight)
                {
                    snapWidth = SnapWidth;
                    snapHeight = SnapWidth * snapImage.Height / snapImage.Width;
                }
                else
                {
                    snapWidth = SnapHeight * snapImage.Width / snapImage.Height;
                    snapHeight = SnapHeight;
                }
            }

            photo.SnapShotWidth = snapWidth;
            photo.SnapShotHeight = snapHeight;

            return photo;
        }

        /// <summary>
        /// 将图片保存到本地
        /// </summary>
        /// <param name="photo"></param>
        /// <returns></returns>
        public static A_Photo SaveToLocal(A_Photo photo)
        {
            if (photo.IsLocal) return ReCalcPhoto(photo);

            Image sourceImg = WebHelper.GetImageFromUrl(photo.Url);
            if (sourceImg == null) return photo;
            Image snapImage = null;
            string albumUrl = Config.UploadDir;
            string resultFileName = Config.GetUniqueName();
            string resultFileUrl = albumUrl + resultFileName + '.' + GetFormat(sourceImg.RawFormat);
            string snapShotUrl = "";

            //如果缩略图和原图不是同一张图，则根据缩略图地址生成新的缩略图
            if (!String.IsNullOrEmpty(photo.SnapShotUrl) && photo.SnapShotUrl != photo.Url)
            {
                snapImage = WebHelper.GetImageFromUrl(photo.SnapShotUrl);
                snapShotUrl = resultFileUrl;
            }

            if (snapImage == null)
            {
                snapImage = sourceImg;
                snapShotUrl = resultFileUrl;
            }

            //如果缩略图太大，则重新生成较小的缩略图
            if (snapImage.Width * snapImage.Height > SnapHeight * SnapWidth * 4)
            {
                snapImage = WebHelper.CreateSnapShot(snapImage, AlbumData.SnapWidth, AlbumData.SnapHeight);
                snapShotUrl = Config.GetAlbumSnapShotUrl(albumUrl) + resultFileName + "_s." + GetFormat(sourceImg.RawFormat);
            }

            photo.Url = resultFileUrl;
            photo.Width = sourceImg.Width;
            photo.Height = sourceImg.Height;
            photo.ImageType = GetFormat(sourceImg.RawFormat);
            photo.SnapShotUrl = snapShotUrl;
            photo.SnapShotWidth = snapImage.Width;
            photo.SnapShotHeight = snapImage.Height;

            sourceImg.Save(HttpContext.Current.Server.MapPath(resultFileUrl), sourceImg.RawFormat);
            if (snapImage != sourceImg)
                snapImage.Save(HttpContext.Current.Server.MapPath(snapShotUrl), sourceImg.RawFormat);
            return photo;
        }

        static string GetFormat(ImageFormat format)
        {
            if (format.Equals(ImageFormat.Jpeg)) return "jpg";
            if (format.Equals(ImageFormat.Gif)) return "gif";
            if (format.Equals(ImageFormat.Png)) return "png";
            if (format.Equals(ImageFormat.Bmp)) return "bmp";
            if (format.Equals(ImageFormat.Icon)) return "ico";
            if (format.Equals(ImageFormat.Emf)) return "emf";
            if (format.Equals(ImageFormat.Exif)) return "exif";
            if (format.Equals(ImageFormat.Tiff)) return "tiff";
            if (format.Equals(ImageFormat.Wmf)) return "wmf";
            return "";
        }

        public static A_Photo GetNextPhoto(A_Photo p)
        {
            if (p.AlbumId == null) return null;
            for (int i = 0; i < p.AlbumId.Photos.Count - 1; i++)
            {
                if (p.AlbumId.Photos[i] == p)
                {
                    return p.AlbumId.Photos[i + 1];
                }
            }
            return null;
        }

        public static A_Photo GetPrevPhoto(A_Photo p)
        {
            if (p.AlbumId == null) return null;
            for (int i = 1; i < p.AlbumId.Photos.Count; i++)
            {
                if (p.AlbumId.Photos[i] == p)
                {
                    return p.AlbumId.Photos[i - 1];
                }
            }
            return null;
        }

        public static void RemovePhotoWhenExpired(string key, string photoIdAndFileName, int delay)
        {
            if (HttpUtils.GetCache()[key] == null)
            {
                DateTime absoluteExpiration = DateTime.Now.Add(new TimeSpan(0, delay, 0));
                HttpUtils.GetCache().Insert(key, photoIdAndFileName, null, absoluteExpiration,
                    Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, new CacheItemRemovedCallback(RemovedCallback));
            }
        }

        static void RemovedCallback(string key, object value, CacheItemRemovedReason reason)
        {
            string[] idAndNames = ((string)value).Split('|');
            A_Photo photo = XpoHelper.GetNewSession().GetObjectByKey<A_Photo>(CommOp.ToInt(idAndNames[0]));
            if (photo == null || photo.AlbumId != null) return;

            string imgPath = idAndNames[1];
            if (File.Exists(imgPath))
                File.Delete(imgPath);

            string snapPath = idAndNames[2];
            if (File.Exists(snapPath))
                File.Delete(snapPath);
            photo.Delete();
        }

        public static XPCollection<A_Article> GetTopAlbum(Session session, int topN, int catId)
        {
            XPCollection<A_Article> albums = new XPCollection<A_Article>(session, CriteriaOperator.Parse("SamplePhotoId IS NOT NULL AND CategoryId=?", catId));
            albums.Sorting.AddRange(ArticleData.GetDefaultSort());
            albums.TopReturnedObjects = topN;
            return albums;
        }

        public static IDataReader GetPagedAlbumsList(DbPager pager)
        {
            return DBHelper.DefaultHelper.ExecPageReader(pager);
        }

        public static void GetPhotos(A_Article article, string ids, bool add)
        {
            IEnumerable<int> pIds = ids.Split(',').Select(id => CommOp.ToInt(id)).Where(i => i > 0);
            if (!add)
            {
                foreach (A_Photo p in article.Photos.ToArray())
                {
                    if (!pIds.Contains(p.Oid))
                    {
                        p.Delete();
                    }
                }
            }

            int orderId = add ? article.Photos.Count + 1 : 1;
            A_Photo top1 = null;
            foreach (int photoId in pIds)
            {
                A_Photo photo = article.Session.GetObjectByKey<A_Photo>(photoId);
                if (photo == null) throw new Exception("没有找到相片");
                photo.AlbumId = article;
                photo.OrderId = orderId++;
                if (top1 == null) top1 = photo;
            }

            if (article.SamplePhotoId == null) article.SamplePhotoId = top1;
        }
    }
}
